home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / COMMON / vgr.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  7KB  |  375 lines

  1. /* --------------------------------- vgr.c ---------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* drawing primitives for a banked video system (like VGA).
  8. */
  9.  
  10. #include "fly.h"
  11. #include "vgr.h"
  12.  
  13.  
  14. #define BANK_FIX(va,vb) \
  15.     if ((Uint)((va)^(vb)) >= 0xc000U) {    \
  16.         va &= 0x0ffffU;            \
  17.         if ((va) >= 0xc000U)        \
  18.             vSetBank (--vBank);    \
  19.         else if ((va) < 0x4000U)    \
  20.             vSetBank (++vBank);    \
  21.     }
  22.  
  23. #define SET_PIXEL(va,c) \
  24.     if (T_MSET == vWriteMode)    \
  25.         vMem[va] = (Uchar)(c);    \
  26.     else if (T_MOR == vWriteMode)    \
  27.         vMem[va] |= (c);    \
  28.     else                \
  29.         vMem[va] ^= (c)
  30.  
  31. static Uchar    FAR *vMem = NULL;
  32. static Uint    vWidth = 0, vHeight = 0, vXBytes = 0;
  33. static void    (FAR *vSetBank) (int bank) = NULL;
  34. static int    (FAR *vSetBase) (Ulong base) = NULL;
  35. static Ulong    vActiveBase = 0;
  36. static int    vBank = 0;
  37. static int    vWriteMode = T_MSET;
  38. static Uint    x1 = 0, y1 = 0, pva = 0, xydone = 0;
  39. #ifdef USE_DIVTAB
  40. static Uint    FAR vDivTab[2048] = {0};
  41. #endif
  42.  
  43. extern int FAR
  44. vSetWriteMode (int mode)
  45. {
  46.     vWriteMode = mode;
  47.     return (0);
  48. }
  49.     
  50. extern int FAR
  51. vSetActive (int page)
  52. {
  53.     vActiveBase = page * (Ulong)vXBytes * (Ulong)vHeight;
  54.     xydone = 0;
  55.     return (0);
  56. }
  57.     
  58. extern int FAR
  59. vSetVisual (int page)            /* Set visual address */
  60. {
  61.     if (vSetBase)
  62.         return (vSetBase (page * (Ulong)vXBytes * (Ulong)vHeight));
  63.     else
  64.         return (1);
  65. }
  66.  
  67. extern int FAR
  68. vSetMem (Uchar *vmem)
  69. {
  70.     vMem = vmem;
  71.     vActiveBase = 0;
  72.     return (0);
  73. }
  74.  
  75. extern int FAR
  76. vSetSize (Uint width, Uint height, Uint xbytes)
  77. {
  78.     vWidth  = width;
  79.     vHeight = height;
  80.     vXBytes = xbytes;
  81.     return (0);
  82. }
  83.  
  84. extern void FAR
  85. vInit (Uchar *vmem, Uint width, Uint height, Uint xbytes,
  86.     void (FAR *setbank) (int page),
  87.     int  (FAR *setbase) (Ulong base))
  88. {
  89.     vMem = vmem;
  90.     vWidth = width;
  91.     vHeight = height;
  92.     vXBytes = xbytes;
  93.     vSetBank = setbank;
  94.     vSetBase = setbase;
  95.  
  96.     vSetWriteMode (T_MSET);
  97.     vSetActive (0);
  98.     vSetVisual (0);
  99.  
  100. #ifdef USE_DIVTAB
  101.     {
  102.         int    i;
  103.  
  104.         vDivTab[0] = 0L;
  105.         for (i = 1; i < rangeof (vDivTab); ++i)
  106.             vDivTab[i] = (Uint)(0x00010000UL / i);
  107.     }
  108. #endif
  109. }
  110.     
  111. /* This does pure C drawing.
  112. */
  113.  
  114. INLINED static Uint NEAR
  115. vILoop (Uint va, Uint dy, Uint dx, int dvx, int dvy, int c)
  116. {
  117.     int    err;        /* conceptualy */
  118.     int    count;
  119.     Uint    vb;
  120.  
  121. /* dx > dy  never =!!!
  122.  * dx > 0
  123.  * dy >= 0
  124.  *
  125.  * set:
  126.  * dy = (dy*0x10000)/dx
  127.  * dx = 0x10000
  128. */
  129.     count = dx;
  130.     err = dx >> 1;
  131.  
  132.     if (T_MSET == vWriteMode) {
  133.         while (--count >= 0) {
  134.             vb = va;
  135.             va += dvx;
  136.             if ((err -= dy) < 0) {
  137.                 err += dx;
  138.                 va += dvy;
  139.             }
  140.             BANK_FIX (va, vb);
  141.             vMem[va] = (Uchar)c;
  142.         }
  143.     } else if (T_MOR == vWriteMode) {
  144.         while (--count >= 0) {
  145.             vb = va;
  146.             va += dvx;
  147.             if ((err -= dy) < 0) {
  148.                 err += dx;
  149.                 va += dvy;
  150.             }
  151.             BANK_FIX (va, vb);
  152.             vMem[va] |= c;
  153.         }
  154.     } else {
  155.         while (--count >= 0) {
  156.             vb = va;
  157.             va += dvx;
  158.             if ((err -= dy) < 0) {
  159.                 err += dx;
  160.                 va += dvy;
  161.             }
  162.             BANK_FIX (va, vb);
  163.             vMem[va] ^= c;
  164.         }
  165.     }
  166.  
  167.     return (va);
  168. }
  169.  
  170. INLINED static Uint NEAR
  171. vSLoop (Uint va, int count, int sv, int c)
  172. {
  173.     Uint    vb;
  174.  
  175.     if (T_MSET == vWriteMode) {
  176.         while (--count >= 0) {
  177.             vb = va;
  178.             va += sv;
  179.             BANK_FIX (va, vb);
  180.             vMem[va] = (Uchar)c;
  181.         }
  182.     } else if (T_MOR == vWriteMode) {
  183.         while (--count >= 0) {
  184.             vb = va;
  185.             va += sv;
  186.             BANK_FIX (va, vb);
  187.             vMem[va] |= c;
  188.         }
  189.     } else {
  190.         while (--count >= 0) {
  191.             vb = va;
  192.             va += sv;
  193.             BANK_FIX (va, vb);
  194.             vMem[va] ^= c;
  195.         }
  196.     }
  197.  
  198.     return (va);
  199. }
  200.  
  201. INLINED static Uint NEAR
  202. vGrAddr (Uint x, Uint y)
  203. {
  204.     Ulong    xy;
  205.     int    bank;
  206.  
  207.     bank = (int)((xy = x + vActiveBase + y*(Ulong)vXBytes) >> 16);
  208.     if (bank != vBank)
  209.         vSetBank (vBank = bank);
  210.  
  211.     return (0x0ffffU & (Uint)xy);
  212. }
  213.  
  214. extern void FAR
  215. vMoveTo (Uint x, Uint y)
  216. {
  217. #if DEBUG_VGR
  218.     if (x >= vWidth)
  219.         x = vWidth-1;
  220.     if (y >= vHeight)
  221.         y = vHeight-1;
  222. #endif
  223.     x1 = x;
  224.     y1 = y;
  225.     xydone = 0;
  226. }
  227.  
  228. extern void FAR
  229. vDrawTo (Uint x2, Uint y2, Uint c)
  230. {
  231.     int    dx, dy, svx, svy;
  232.     int    t;
  233.  
  234. #if DEBUG_VGR
  235.     if (x2 >= vWidth)
  236.         x2 = vWidth-1;
  237.     if (y2 >= vHeight)
  238.         y2 = vHeight-1;
  239. #endif
  240.     t = 0;
  241.     if (!xydone) {
  242.         t = 1;
  243.         xydone = 1;
  244.         pva = vGrAddr (x1, y1);
  245.         SET_PIXEL (pva, c);
  246.     }
  247.  
  248.     svx = 1;
  249.     if ((dx = x2 - x1) < 0) {
  250.         dx = -dx;
  251.         svx = -1;
  252.     }
  253.  
  254.     svy = vXBytes;
  255.     if ((dy = y2 - y1) < 0) {
  256.         dy = -dy;
  257.         svy = -svy;
  258.     }
  259.  
  260.     if (dx > dy) {
  261.         if (0 == dy) {
  262.             Uint    vb;
  263.  
  264.             vb = pva + x2 - x1;    /* end point */
  265.  
  266.             if (!((Uint)((pva)^(vb)) >= 0xc000U &&
  267.                     (vb >= 0xc000U || vb < 0x4000U))
  268.             && (T_MSET == vWriteMode)
  269.             ) {
  270.                 memset (vMem + (svx>0 ? pva+1 : vb), c, dx);
  271.                 pva = vb;
  272.             } else
  273.                 pva = vSLoop (pva, dx, svx, c);
  274.         } else
  275.             pva = vILoop (pva, dy, dx, svx, svy, c);
  276.         ++GrStats[dx+t];
  277.     } else if (dx < dy) {
  278.         if (0 == dx)
  279.             pva = vSLoop (pva, dy, svy, c);
  280.         else
  281.             pva = vILoop (pva, dx, dy, svy, svx, c);
  282.         ++GrStats[dy+t];
  283.     } else /* if (dx == dy) */ {
  284.         if (dx)
  285.             pva = vSLoop (pva, dx, svx+svy, c);
  286.         ++GrStats[dx+t];
  287.     }
  288.  
  289.     x1 = x2;
  290.     y1 = y2;
  291. }
  292.  
  293. /* Based on the acm version from TOG V11N3 (July 1992), this one is
  294.  * modified to do 2 quads at a time to limit VGA bank flips.
  295. */
  296.  
  297. #define POINT(x,y,c) \
  298.     do {                             \
  299.         if (xy = xxyy+(x)+(y), (int)(xy>>16) != vBank)    \
  300.             vSetBank (vBank = (int)(xy>>16));    \
  301.         va = 0x0ffffU & (Uint)xy;            \
  302.         SET_PIXEL (va, c);                 \
  303.     } while (0)
  304.  
  305. #define INCX() \
  306.     (x++, b2x += b2, dxt += d2xt, t += dxt)
  307.  
  308. #define INCY() \
  309.     (y--, a2y -= a2, dyt += d2yt, t += dyt, yy -= vXBytes)
  310.  
  311. extern void FAR
  312. vEllipse (Uint xc, Uint yc, Uint a, Uint b, Uint c)
  313. {
  314.     long    xxyy;
  315.     Ulong    xy;
  316.     Uint    va = 0;
  317.     int    x = 0, y = b;
  318.     long    yy = y*(long)vXBytes;
  319.     long    a2 = (long)a*a, b2 = (long)b*b;
  320.     long    crit1 = -(a2/4 + a%2 + b2);
  321.     long    crit2 = -(b2/4 + b%2 + a2);
  322.     long    crit3 = -(b2/4 + b%2);
  323.     long    t = -a2*y;
  324.     long    dxt = 2*b2*x, dyt = -2*a2*y;
  325.     long    d2xt = 2*b2, d2yt = 2*a2;
  326.     long    b2x = b2*x, a2y = a2*y;
  327.  
  328.     if (xc < a || xc+a >= vWidth ||
  329.         yc < b || yc+b >= vHeight)
  330.         return;
  331.  
  332.     xxyy = xc + vActiveBase + yc * (long)vXBytes;
  333.  
  334.     while (y >= 0 && x <= (int)a) {
  335.         POINT (x, yy, c);
  336.         if (x && y)
  337.             POINT (-x,  yy, c);
  338.         if (t + b2x <= crit1 || t + a2y <= crit3)
  339.             INCX ();
  340.         else if (t - a2y > crit2)
  341.             INCY ();
  342.         else {
  343.             INCX ();
  344.             INCY ();
  345.         }
  346.     }
  347.  
  348.     x = 0, y = b;
  349.     yy = y*(long)vXBytes;
  350.     t = -a2*y;
  351.     dxt = 2*b2*x, dyt = -2*a2*y;
  352.     d2xt = 2*b2, d2yt = 2*a2;
  353.     b2x = b2*x, a2y = a2*y;
  354.  
  355.     while (y >= 0 && x <= (int)a) {
  356.         if (x || y)
  357.             POINT (-x, -yy, c);
  358.         if (x && y)
  359.             POINT ( x, -yy, c);
  360.         if (t + b2x <= crit1 || t + a2y <= crit3)
  361.             INCX ();
  362.         else if (t - a2y > crit2)
  363.             INCY ();
  364.         else {
  365.             INCX ();
  366.             INCY ();
  367.         }
  368.     }
  369. }
  370. #undef BANK_FIX
  371. #undef SET_PIXEL
  372. #undef POINT
  373. #undef INCX
  374. #undef INCY
  375.